#!/bin/bash
#
# 配置 SSL 证书自动续期
# 作者: 知汛项目组
# 最后更新: 2024-11-07

set -e

# 颜色定义
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
RED='\033[0;31m'
NC='\033[0m'

# 默认配置
TEST_MODE=false

# 显示帮助
show_help() {
    cat << EOF
用法: $0 [选项]

配置 Let's Encrypt 证书自动续期

选项:
    --test    测试续期（不实际执行）
    --help    显示此帮助信息

示例:
    # 配置自动续期
    sudo bash $0

    # 测试续期
    sudo bash $0 --test
EOF
}

# 解析参数
while [[ $# -gt 0 ]]; do
    case $1 in
        --test)
            TEST_MODE=true
            shift
            ;;
        --help)
            show_help
            exit 0
            ;;
        *)
            echo -e "${RED}未知参数: $1${NC}"
            show_help
            exit 1
            ;;
    esac
done

# 检查root权限
if [ "$EUID" -ne 0 ]; then
    echo -e "${RED}请使用root权限运行: sudo $0${NC}"
    exit 1
fi

echo "======================================"
echo "配置 SSL 证书自动续期"
echo "======================================"
echo ""

# 测试续期
if [ "$TEST_MODE" = true ]; then
    echo -e "${YELLOW}测试续期...${NC}"
    certbot renew --dry-run
    
    if [ $? -eq 0 ]; then
        echo -e "${GREEN}✓ 续期测试成功${NC}"
    else
        echo -e "${RED}✗ 续期测试失败${NC}"
        exit 1
    fi
    exit 0
fi

# 创建续期钩子目录
echo -e "${YELLOW}[1/3] 创建续期钩子...${NC}"

mkdir -p /etc/letsencrypt/renewal-hooks/deploy

# 创建部署钩子脚本
cat > /etc/letsencrypt/renewal-hooks/deploy/update-all-certs.sh <<'EOF'
#!/bin/bash
# 证书续期后自动部署到所有服务

DOMAIN="ws.waterism.tech"
CERT_DIR="/etc/letsencrypt/live/$DOMAIN"

echo "[$(date)] Starting certificate deployment..."

# 部署到前端应用
if [ -d "/opt/ssl/zhixun-app" ]; then
    cp "$CERT_DIR/fullchain.pem" /opt/ssl/zhixun-app/
    cp "$CERT_DIR/privkey.pem" /opt/ssl/zhixun-app/
    chmod 644 /opt/ssl/zhixun-app/fullchain.pem
    chmod 600 /opt/ssl/zhixun-app/privkey.pem
    echo "[$(date)] Frontend certificate updated"
fi

# 部署到Hitch（API和CDN）
if [ -d "/etc/hitch/certs" ]; then
    # API证书
    cat "$CERT_DIR/fullchain.pem" "$CERT_DIR/privkey.pem" > /etc/hitch/certs/api.pem
    chmod 600 /etc/hitch/certs/api.pem
    chown hitch:hitch /etc/hitch/certs/api.pem 2>/dev/null || chown root:root /etc/hitch/certs/api.pem
    
    # CDN证书
    cat "$CERT_DIR/fullchain.pem" "$CERT_DIR/privkey.pem" > /etc/hitch/certs/cdn.pem
    chmod 600 /etc/hitch/certs/cdn.pem
    chown hitch:hitch /etc/hitch/certs/cdn.pem 2>/dev/null || chown root:root /etc/hitch/certs/cdn.pem
    
    echo "[$(date)] Hitch certificates updated"
fi

# 重载服务
systemctl reload nginx 2>/dev/null || true
systemctl reload hitch 2>/dev/null || true
systemctl reload hitch-cdn 2>/dev/null || true
docker restart zhixun-app 2>/dev/null || true

echo "[$(date)] Certificate deployment completed"
EOF

chmod +x /etc/letsencrypt/renewal-hooks/deploy/update-all-certs.sh

echo -e "${GREEN}✓ 续期钩子已创建${NC}"

# 配置 cron 任务
echo -e "${YELLOW}[2/3] 配置 cron 任务...${NC}"

# 检查是否已有 certbot 的 systemd timer
if systemctl list-timers | grep -q certbot; then
    echo -e "${GREEN}✓ 已有 systemd timer，无需添加 cron${NC}"
else
    # 添加 cron 任务
    CRON_CMD="0 2 * * * certbot renew --quiet --deploy-hook '/etc/letsencrypt/renewal-hooks/deploy/update-all-certs.sh'"
    
    # 检查是否已存在
    if crontab -l 2>/dev/null | grep -q "certbot renew"; then
        echo -e "${GREEN}✓ cron 任务已存在${NC}"
    else
        (crontab -l 2>/dev/null; echo "$CRON_CMD") | crontab -
        echo -e "${GREEN}✓ cron 任务已添加${NC}"
    fi
fi

# 测试配置
echo -e "${YELLOW}[3/3] 测试配置...${NC}"

certbot renew --dry-run

if [ $? -eq 0 ]; then
    echo -e "${GREEN}✓ 配置测试成功${NC}"
else
    echo -e "${RED}✗ 配置测试失败${NC}"
    exit 1
fi

echo ""
echo -e "${GREEN}✓ 自动续期配置完成${NC}"
echo ""
echo "续期说明:"
echo "  - 自动检查: 每天凌晨2点"
echo "  - 续期时机: 证书过期前30天"
echo "  - 证书有效期: 90天"
echo ""
echo "查看续期日志:"
echo "  sudo journalctl -u certbot-renew"
echo "  sudo tail -f /var/log/letsencrypt/letsencrypt.log"

